using System;
using System.IO;
using FireStarterModeller.BO;
using Microsoft.Build.BuildEngine;

namespace FireStarter.CodeGeneration
{
    //struct ClassFileNamePair
    //{
    //    public ClassFileNamePair( string stubFileName, string defFileName)
    //    {
    //        DefFileName = defFileName;
    //        StubFileName = stubFileName;
    //    }

    //    public string DefFileName;
    //    public string StubFileName;
    //}

    public enum OutputType
    {
        WinExe,
        Library
    }

    //enum ProjectType
    //{
    //    Base,
    //    UI,
    //    Logic,
    //    BO
    //}

	public class ProjectFileManager
	{
	    private readonly string _projectFileName;
	    private readonly bool _isWebProject;
	    private readonly CodeTemplateEnum _codeTemplate;
	    private Project _project;
	    private BuildPropertyGroup _projectPropertiesGroup;
	    private BuildItemGroup _compileItemsGroup;
	    private BuildItemGroup _referencesGroup;
	    //private ProjectFileDetails _projectFileDetails;
        //private DefProject _defProject;
        //private List<ProjectFileDetails> _referencedProjectFiles;
        public const string WEB_PROJECT_GUIDS = "{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}";

	    public ProjectFileManager(string projectFileName, OutputType outputType, CodeTemplateEnum codeTemplate)
            : this(projectFileName, outputType, false, codeTemplate)
	    {}

	    public ProjectFileManager(string projectFileName, OutputType outputType, bool isWebProject, CodeTemplateEnum codeTemplate)
            : this(projectFileName, outputType, isWebProject, null, codeTemplate)
        {}

        public ProjectFileManager(string projectFileName, OutputType outputType, bool isWebProject, string csProjXml, CodeTemplateEnum codeTemplate)
        {
            if (projectFileName == null) throw new ArgumentNullException("projectFileName");

            _codeTemplate = codeTemplate;
            if (String.IsNullOrEmpty(csProjXml))
            {
                csProjXml = TemplateLoader.Csproj(codeTemplate);
            }

            _projectFileName = projectFileName;
            CSProjXml = csProjXml;
            _isWebProject = isWebProject;
            LoadProjectFile(outputType);
        }

	    public ProjectFileManager(string projectFileName, CodeTemplateEnum codeTemplate)
	    {
	        if (projectFileName == null) throw new ArgumentNullException("projectFileName");
	        _projectFileName = projectFileName;
	        _codeTemplate = codeTemplate;
            CSProjXml = TemplateLoader.Csproj(codeTemplate);
	        LoadProjectFile();
	    }

	    public string ProjectFileName
	    {
	        get { return _projectFileName; }
	    }



	    public Guid ProjectGuid
	    {
            get
            {
                BuildProperty buildProperty = GetBuildProperty(_projectPropertiesGroup, "ProjectGuid");
                if (buildProperty == null) return Guid.Empty;
                string value = buildProperty.Value;
                return new Guid(value);
            }
            private set
            {
                SetOrCreateProperty(_projectPropertiesGroup, "ProjectGuid", value.ToString("B"));
            }
	    }

        public string ProjectTypeGuids
        {
            get
            {
                BuildProperty buildProperty = GetBuildProperty(_projectPropertiesGroup, "ProjectTypeGuids");
                if (buildProperty == null) return "";
                string value = buildProperty.Value;
                return value;
            }
            private set
            {
                SetOrCreateProperty(_projectPropertiesGroup, "ProjectTypeGuids", value);
            }
        }


	    public string RootNamespace
	    {
            get
            {
                BuildProperty buildProperty = GetBuildProperty(_projectPropertiesGroup, "RootNamespace");
                if (buildProperty == null) return null;
                return buildProperty.Value;
            }
            private set
            {
                SetOrCreateProperty(_projectPropertiesGroup, "RootNamespace", value);
            }
	    }

        public string AssemblyName
	    {
            get
            {
                BuildProperty buildProperty = GetBuildProperty(_projectPropertiesGroup, "AssemblyName");
                if (buildProperty == null) return null;
                return buildProperty.Value;
            }
            private set
            {
                SetOrCreateProperty(_projectPropertiesGroup, "AssemblyName", value);
            }
	    }

        public OutputType OutputType
	    {
            get
            {
                BuildProperty buildProperty = GetBuildProperty(_projectPropertiesGroup, "OutputType");
                if (buildProperty == null)
                {
                    OutputType defaultOutputType = OutputType.Library;
                    SetOrCreateProperty(_projectPropertiesGroup, "OutputType", defaultOutputType.ToString());
                    return defaultOutputType;
                }
                return (OutputType)Enum.Parse(typeof(OutputType), buildProperty.Value);
            }
            private set
            {
                SetOrCreateProperty(_projectPropertiesGroup, "OutputType", value.ToString());
            }
	    }

	    public bool IsWebProject
	    {
	        get { return _isWebProject; }
	    }

	    private void LoadProjectFile()
	    {
	        LoadProjectFile(OutputType.Library);
	    }

        private void LoadProjectFile(OutputType outputType)
        {

            //Engine.GlobalEngine.BinPath = Path.GetDirectoryName(typeof (object).Assembly.Location);
            //Engine.GlobalEngine.BinPath = @"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727";
            _project = new Project();
            
            if (File.Exists(_projectFileName))
            {
                _project.Load(_projectFileName);
                SetupProjectVariables();
                //GetProjectDetails(project);
            }
            else
            {
                _project.LoadXml(CSProjXml);
                SetupProjectVariables();
                SetupNewProjectFile(outputType);
            }
            //ConfigureProjectFile(project, outputType, projectType);
            //AddProjectCompileItems(project, classFileNamePairs);
            
            //if (projectType == ProjectType.BO)
            //{
            //    AddProjectContentItem(project, Path.Combine(_projectFileDetails.Directory, "ClassDefs.xml"), true);
            //    AddPostBuildClassDefCommand(project);
            //}
            
            //AddRequiredProjectFiles(outputType);

        }

	    private string CSProjXml { get; set; }

	    private void SetupProjectVariables()
	    {
            _projectPropertiesGroup = GetProjectPropertiesGroup();
	        _compileItemsGroup = GetCompileItemsGroup();
	        _referencesGroup = GetBuildItemGroup(_project, "Reference");
	    }

	    public void SaveProjectFile()
        {
            if (_project.IsDirty)
            {
                string directoryName = Path.GetDirectoryName(_projectFileName);
                if (!Directory.Exists(directoryName))
                {
                    Directory.CreateDirectory(directoryName);
                }
                _project.Save(_projectFileName);
            }
        }

        public string GetCurrentProjectFileXml()
        {
            return _project.Xml;
        }

        private void SetupNewProjectFile(OutputType outputType)
        {
            //Setup project properties
            ProjectGuid = Guid.NewGuid();
            if(IsWebProject)
                   ProjectTypeGuids = WEB_PROJECT_GUIDS;
            string assemblyName = Path.GetFileNameWithoutExtension(_projectFileName);
            if (assemblyName != null)
            {
                RootNamespace = assemblyName;
                AssemblyName = assemblyName;
            } else
            {
                throw new Exception("assemblyName Cannot be null");
            }
            OutputType = outputType;
        }

        public void AddCodeFile(string fileName)
        {
            AddCodeFile(fileName, null);
        }

        public void AddCodeFile(string fileName, string dependantUponFile)
        {
            string relativeFileName = GetRelativeProjectPath(fileName);
            BuildItem buildItem = FindOrCreateItem(_compileItemsGroup, "Compile", relativeFileName);
            if (!String.IsNullOrEmpty(dependantUponFile))
            {
                //string pathToDependency = GetRelativeProjectPath(dependantUponFile);
                string pathToDependency = Path.GetFileName(dependantUponFile);
                buildItem.SetMetadata("DependentUpon", pathToDependency);
            }
        }

        public void AddFolder(string folderPath)
        {
            string relativeFileName = GetRelativeProjectPath(folderPath);
            BuildItem buildItem = FindOrCreateItem(_compileItemsGroup, "Folder", relativeFileName);
        }

        public bool HasCodeFile(string fileName)
        {
            return HasFileBuildItem(fileName, "Compile");
        }

        public bool HasCodeFile(string fileName, string dependantOnFileName)
        {
            BuildItem buildItem;
            if (HasFileBuildItem(fileName, "Compile", out buildItem))
            {
                dependantOnFileName = GetRelativeProjectPath(dependantOnFileName);
                string dependentOn = buildItem.GetMetadata("DependentUpon");
                return (dependentOn == dependantOnFileName);
            }
            else
            {
                return false;
            }
        }

        public void AddContentFile(string fileName)
        {
            AddContentFile(fileName, null);
        }

        public void AddContentFile(string fileName, string dependantUponFile)
        {
            string relativeFileName = GetRelativeProjectPath(fileName);
            BuildItem buildItem = FindOrCreateItem(_compileItemsGroup, "Content", relativeFileName);
            if (!String.IsNullOrEmpty(dependantUponFile))
            {
                dependantUponFile = GetRelativeProjectPath(dependantUponFile);
                buildItem.SetMetadata("DependentUpon", dependantUponFile);
            }
        }

        public bool HasContentFile(string fileName)
        {
            return HasFileBuildItem(fileName, "Content");
        }

        public bool HasContentFile(string fileName, string dependantOnFileName)
        {
            BuildItem buildItem;
            if (HasFileBuildItem(fileName, "Content", out buildItem))
            {
                dependantOnFileName = GetRelativeProjectPath(dependantOnFileName);
                string dependentOn = buildItem.GetMetadata("DependentUpon");
                return (dependentOn == dependantOnFileName);
            }
            else
            {
                return false;
            }
        }

	    public void AddFile(string fileName)
        {
            string relativeFileName = GetRelativeProjectPath(fileName);
            BuildItem buildItem = FindOrCreateItem(_compileItemsGroup, "None", relativeFileName);
        }

        public bool HasFile(string fileName)
        {
            return HasFileBuildItem(fileName, "None");
        }

        public void AddResourceFile(string resourceFileName, string designerFileName)
        {
            string resourceFileNameRelative = GetRelativeProjectPath(resourceFileName);
            string resourceFileNameOnly = Path.GetFileName(resourceFileName);
            string designerFileNameRelative = GetRelativeProjectPath(designerFileName);
            string designerFileNameOnly = Path.GetFileName(designerFileName);
            BuildItem buildItem;
            buildItem = FindOrCreateItem(_compileItemsGroup, "EmbeddedResource", resourceFileNameRelative);
            buildItem.SetMetadata("Generator", "ResXFileCodeGenerator");
            buildItem.SetMetadata("LastGenOutput", designerFileNameOnly);
            buildItem.SetMetadata("SubType", "Designer");
            buildItem = FindOrCreateItem(_compileItemsGroup, "Compile", designerFileNameRelative);
            buildItem.SetMetadata("AutoGen", "True");
            buildItem.SetMetadata("DependentUpon", resourceFileNameOnly);
        }

        public void AddEmbeddedResourceFile(string fileName)
        {
            string relativeFileName = GetRelativeProjectPath(fileName);
            BuildItem buildItem = FindOrCreateItem(_compileItemsGroup, "EmbeddedResource", relativeFileName);
        }

        public bool HasResourceFile(string resourceFileName)
        {
            return HasFileBuildItem(resourceFileName, "EmbeddedResource");
        }

        public void AddSettingsFile(string settingsFileName, string designerFileName)
        {
            string settingsFileNameRelative = GetRelativeProjectPath(settingsFileName);
            string settingsFileNameOnly = Path.GetFileName(settingsFileName);
            string designerFileNameRelative = GetRelativeProjectPath(designerFileName);
            string designerFileNameOnly = Path.GetFileName(designerFileName);
            BuildItem buildItem;
            buildItem = FindOrCreateItem(_compileItemsGroup, "None", settingsFileNameRelative);
            buildItem.SetMetadata("Generator", "SettingsSingleFileGenerator");
            buildItem.SetMetadata("LastGenOutput", designerFileNameOnly);
            buildItem.SetMetadata("SubType", "Designer");
            buildItem = FindOrCreateItem(_compileItemsGroup, "Compile", designerFileNameRelative);
            buildItem.SetMetadata("AutoGen", "True");
            buildItem.SetMetadata("DependentUpon", settingsFileNameOnly);
            buildItem.SetMetadata("DesignTimeSharedInput", "True");
        }

        public bool HasSettingsFile(string settingsFileName)
        {
            return HasFileBuildItem(settingsFileName, "None");
        }

	    private bool HasFileBuildItem(string fileName, string itemName)
	    {
	        BuildItem buildItem;
	        return HasFileBuildItem(fileName, itemName, out buildItem);
	    }

	    private bool HasFileBuildItem(string fileName, string itemName, out BuildItem buildItem)
	    {
	        BuildItemGroup foundItemGroup;
            
	        string relativeFileName = GetRelativeProjectPath(fileName);
	        buildItem = GetBuildItem(itemName, relativeFileName, out foundItemGroup);
	        return buildItem != null;
	    }

        public void AddReference(string dllFileName)
        {
            string assemblyName = Path.GetFileNameWithoutExtension(dllFileName);
            AddReference(assemblyName, dllFileName);
        }

        public void AddSystemReference(string systemReference)
        {
            AddReference(systemReference, "");
        }

        public bool HasReference(string dllFileName)
        {
            string assemblyName = Path.GetFileNameWithoutExtension(dllFileName);
            return FindReference(assemblyName) != null;
        }

        public bool HasSystemReference(string systemReference)
        {
            return FindReference(systemReference) != null;
        }

        private void AddReference(string assemblyName, string hintPath)
        {
            BuildItem foundBuildItem = FindReference(assemblyName);
            string hintPathFull = null;
            if (!String.IsNullOrEmpty(hintPath))
            {
                hintPathFull = hintPath; //Path.Combine(hintPath, assemblyName + ".dll");
                hintPathFull = GetRelativeProjectPath(hintPathFull);
            }
            if (foundBuildItem == null)
            {
                BuildItem buildItem = _referencesGroup.AddNewItem("Reference", assemblyName);
                if (!String.IsNullOrEmpty(hintPathFull))
                {
                    buildItem.SetMetadata("HintPath", hintPathFull);
                }
            }
            else
            {
                if (!String.IsNullOrEmpty(hintPathFull))
                {
                    foundBuildItem.SetMetadata("HintPath", hintPathFull);
                }
            }
        }

        private BuildItem FindReference(string assemblyName)
        {
            return FindReference("Reference", assemblyName);
        }

        private BuildItem FindProjectReference(string projectFileName)
        {
            return FindReference("ProjectReference", projectFileName);
        }

        private BuildItem FindReference(string referenceType, string assemblyName)
        {
            foreach (BuildItemGroup buildItemGroup in _project.ItemGroups)
            {
                BuildItem buildItem = FindReferenceInGroup(buildItemGroup, assemblyName, referenceType);
                if (buildItem != null) return buildItem;
            }
            return null;
        }

	    private static BuildItem FindReferenceInGroup(BuildItemGroup buildItemGroup, string assemblyName, string referenceType)
	    {
	        BuildItem foundBuildItem = null;
	        string suffix = ", Version=".ToLower();
	        foreach (BuildItem buildItem in buildItemGroup)
	        {
	            string currentName = buildItem.Include.ToLower();
	            assemblyName = assemblyName.ToLower();
	            if (buildItem.Name == referenceType &&
	                (currentName == assemblyName || currentName.StartsWith(assemblyName + suffix)))
	            {
	                foundBuildItem = buildItem;
	                break;
	            }
	        }
	        return foundBuildItem;
	    }

	    public bool HasProjectReference(string projectFileName)
        {
            string relativeProjectFileName = GetRelativeProjectPath(projectFileName);
            return FindProjectReference(relativeProjectFileName) != null;
        }

        public void AddProjectReference(string projectName, string solutionDirectory)
        {
            if (String.IsNullOrEmpty(projectName)) return;
            string projectFileName = GetFullProjectPath(projectName, solutionDirectory);
            ProjectFileManager projectFileManager = new ProjectFileManager(projectFileName, OutputType.Library, _codeTemplate);
            string relativeProjectFileName = GetRelativeProjectPath(projectFileName);
            if (FindReference(relativeProjectFileName) != null) return;
            //BuildItemGroup projectReferenceItemsGroup = GetBuildItemGroup(project, "Compile");
            BuildItem buildItem = FindOrCreateItem(_referencesGroup, "ProjectReference", relativeProjectFileName);
            buildItem.SetMetadata("Project", projectFileManager.ProjectGuid.ToString("B").ToUpper());
            buildItem.SetMetadata("Name", projectName);
        }

        public static string GetFullProjectPath(string projectName, string solutionDirectory)
        {
            if (projectName == null) return null;
            if (solutionDirectory == null) return projectName;
            //string directoryName = Path.GetFileNameWithoutExtension(projectName);
            return solutionDirectory + Path.DirectorySeparatorChar + projectName +
                Path.DirectorySeparatorChar + projectName + ".csproj";
        }



	    //private void AddLicenseContentIfExists(Project project)
        //{
        //    DirectoryInfo dirInfo = new DirectoryInfo(Application.StartupPath);
        //    FileInfo[] files = dirInfo.GetFiles("license.license");
        //    if (files.Length == 0)
        //    {
        //        files = dirInfo.GetFiles("*.license");
        //    }
        //    if (files.Length > 0)
        //    {
        //        FileInfo fileInfo = files[0];
        //        AddProjectContentItem(project, fileInfo.FullName, true);
        //    }
        //}

        //private void AddRequiredProjectFiles(OutputType outputType)
        //{
        //    string fileContents;
        //    fileContents = TemplateLoader.AssemblyInfo_cs(_projectFileDetails.Name);
        //    CreateFile(_projectFileDetails.Directory, @"Properties\AssemblyInfo.cs", fileContents);
        //    if (outputType == OutputType.WinExe)
        //    {
        //        fileContents = TemplateLoader.App_config(_defProject.ProjectSettings.DatabaseConfig);
        //        CreateFile(_projectFileDetails.Directory, @"App.Config", fileContents);
        //        fileContents = TemplateLoader.Resources_resx();
        //        CreateFile(_projectFileDetails.Directory, @"Properties\Resources.resx", fileContents);
        //        fileContents = TemplateLoader.Resources_Designer_cs(_projectFileDetails.Name);
        //        CreateFile(_projectFileDetails.Directory, @"Properties\Resources.Designer.cs", fileContents);
        //        fileContents = TemplateLoader.Settings_settings();
        //        CreateFile(_projectFileDetails.Directory, @"Properties\Settings.settings", fileContents);
        //        fileContents = TemplateLoader.Settings_Designer_cs(_projectFileDetails.Name);
        //        CreateFile(_projectFileDetails.Directory, @"Properties\Settings.Designer.cs", fileContents);
        //    }
        //}

        //private void GetProjectDetails(Project project)
        //{
        //    BuildPropertyGroup projectPropertiesGroup = GetProjectPropertiesGroup(project);
        //    BuildProperty buildProperty = GetBuildProperty(projectPropertiesGroup, "ProjectGuid");
        //    if (buildProperty != null)
        //    {
        //        _projectFileDetails.ProjectGuid = new Guid(buildProperty.Value);
        //    }
        //}

        

        //private void ConfigureProjectFile(Project project, OutputType outputType, ProjectType projectType)
        //{
        //    AddProjectReferences(project, projectType);

        //    //Add required file references
        //    BuildItemGroup compileItemsGroup = GetBuildItemGroup(project, "Compile");
        //    FindOrCreateItem(compileItemsGroup, "Compile", @"Properties\AssemblyInfo.cs");
        //    if (outputType == OutputType.WinExe)
        //    {
        //        BuildItem buildItem;
        //        buildItem = FindOrCreateItem(compileItemsGroup, "None", @"App.Config");

        //        buildItem = FindOrCreateItem(compileItemsGroup, "None", @"Properties\Settings.settings");
        //        buildItem.SetMetadata("Generator", "SettingsSingleFileGenerator");
        //        buildItem.SetMetadata("LastGenOutput", "Settings.Designer.cs");
        //        buildItem = FindOrCreateItem(compileItemsGroup, "Compile", @"Properties\Settings.Designer.cs");
        //        buildItem.SetMetadata("AutoGen", "True");
        //        buildItem.SetMetadata("DependentUpon", "Settings.settings");
        //        buildItem.SetMetadata("DesignTimeSharedInput", "True");
        //    }
        //}

        //private void AddPostBuildClassDefCommand(Project project)
        //{
        //    BuildPropertyGroup buildEventPropertyGroup;
        //    buildEventPropertyGroup = GetBuildPropertyGroup(project, "PostBuildEvent");
        //    if (buildEventPropertyGroup == null)
        //        buildEventPropertyGroup = GetBuildPropertyGroup(project, "PreBuildEvent");
        //    if (buildEventPropertyGroup == null)
        //        buildEventPropertyGroup = project.AddNewPropertyGroup(false);
        //    BuildProperty buildProperty = GetBuildProperty(buildEventPropertyGroup, "PostBuildEvent");
        //    if (String.IsNullOrEmpty(buildProperty.Value))
        //    {
        //        SetOrCreateProperty(buildEventPropertyGroup, "PostBuildEvent",
        //                            String.Format(
        //                                "copy \"$(ProjectDir)ClassDefs.xml\" \"$(SolutionDir){0}\\$(OutDir)\"",
        //                                _defProject.ProjectSettings.BaseProjectName));
        //    }
        //}

        private BuildPropertyGroup GetProjectPropertiesGroup()
        {
            BuildPropertyGroup projectPropertiesGroup = GetBuildPropertyGroup(_project, "AssemblyName");
            if (projectPropertiesGroup == null)
                projectPropertiesGroup = GetBuildPropertyGroup(_project, "ProjectGuid");
            if (projectPropertiesGroup == null)
                projectPropertiesGroup = GetBuildPropertyGroup(_project, "ProjectTypeGuids");
            if (projectPropertiesGroup == null)
                projectPropertiesGroup = GetBuildPropertyGroup(_project, "RootNamespace");
            if (projectPropertiesGroup == null)
                projectPropertiesGroup = GetBuildPropertyGroup(_project, "ProductVersion");
            if (projectPropertiesGroup == null)
                projectPropertiesGroup = GetBuildPropertyGroup(_project, "SchemaVersion");
            if (projectPropertiesGroup == null)
                projectPropertiesGroup = _project.AddNewPropertyGroup(false);
            return projectPropertiesGroup;
        }

        private BuildItemGroup GetCompileItemsGroup()
        {
            BuildItemGroup compileItemsGroup = GetBuildItemGroup(_project, "Compile"); ;
            return compileItemsGroup;
        }

        //private void AddProjectCompileItems(Project project, List<ClassFileNamePair> classFileNamePairs)
        //{
        //    if (classFileNamePairs == null) return;
        //    BuildItemGroup compileItemGroup = GetBuildItemGroup(project, "Compile");
        //    foreach (ClassFileNamePair classFileNamePair in classFileNamePairs)
        //    {
        //        FindOrCreateItem(compileItemGroup, "Compile", GetRelativePath(classFileNamePair.StubFileName, _projectFileDetails.Directory));
        //        if (classFileNamePair.DefFileName.Length > 0)
        //        {
        //            BuildItem newItem;
        //            newItem = FindOrCreateItem(compileItemGroup, "Compile", GetRelativePath(classFileNamePair.DefFileName, _projectFileDetails.Directory));
        //            newItem.SetMetadata("DependentUpon", GetRelativePath(classFileNamePair.StubFileName, _projectFileDetails.Directory));
        //        }
        //    }
        //}

        //private void AddProjectContentItem(Project project, string contentFileName, bool copyToOutputDir)
        //{
        //    if (string.IsNullOrEmpty(contentFileName)) return;
        //    BuildItemGroup contentItemGroup = GetBuildItemGroup(project, "ReplaceWithString");
        //    BuildItem newItem = FindOrCreateItem(contentItemGroup, "ReplaceWithString", GetRelativePath(contentFileName, _projectFileDetails.Directory));
        //    if (copyToOutputDir)
        //    {
        //        newItem.SetMetadata("CopyToOutputDirectory", "Always"); // "PreserveNewest");
        //    }
        //}

        //#region Project References

        //private void AddProjectReferences(Project project, ProjectType projectType)
        //{
        //    //Add required references
        //    BuildItemGroup referencesGroup = GetBuildItemGroup(project, "Reference");
        //    string habaneroHintPath = _defProject.ProjectSettings.HabaneroDllPath;
        //    AddReference(referencesGroup, "Habanero.Base", habaneroHintPath);
        //    AddReference(referencesGroup, "Habanero.BO", habaneroHintPath);
        //    AddReference(referencesGroup, "Habanero.Util", habaneroHintPath);
        //    switch (projectType)
        //    {
        //        case ProjectType.Base:
        //            //AddProjectReference(project, _defProject.ProjectSettings.UiProjectName);
        //            AddReference(referencesGroup, "Habanero.Faces.Base", habaneroHintPath);
        //            AddReference(referencesGroup, "Habanero.Faces.Win", habaneroHintPath);
        //            AddReference(referencesGroup, "System.Deployment");
        //            AddReference(referencesGroup, "System.Drawing");
        //            AddReference(referencesGroup, "System.Windows.Forms");
        //            break;
        //        case ProjectType.UI:
        //            //AddProjectReference(project, _defProject.ProjectSettings.LogicProjectFileName);
        //            //AddProjectReference(project, _defProject.ProjectSettings.BoProjectFileName);
        //            AddReference(referencesGroup, "Habanero.Faces.Base", habaneroHintPath);
        //            AddReference(referencesGroup, "Habanero.Faces.Win", habaneroHintPath);
        //            AddReference(referencesGroup, "System.Deployment");
        //            AddReference(referencesGroup, "System.Drawing");
        //            AddReference(referencesGroup, "System.Windows.Forms");
        //            break;
        //        case ProjectType.Logic:
        //            //AddProjectReference(project, _defProject.ProjectSettings.BoProjectFileName);
        //            break;
        //        case ProjectType.BO:
        //            AddReference(referencesGroup, "Habanero.DB", habaneroHintPath);
        //            break;
        //    }

        //    foreach (ProjectFileDetails projectFileDetails in _referencedProjectFiles)
        //    {
        //        AddProjectReference(project, projectFileDetails);
        //    }
        //}

        

        

        //#endregion //Project References

        #region Utility Methods

        public string GetRelativeProjectPath(string absolutePath)
        {
            string projectPath = Path.GetFullPath(_projectFileName);
            projectPath = Path.GetDirectoryName(projectPath);
            absolutePath = Path.GetFullPath(absolutePath);
            return Utilities.GetRelativePath(absolutePath, projectPath);
        }

        #region Property Utilities

        private static BuildPropertyGroup GetBuildPropertyGroup(Project project, string propertyName)
        {
            BuildPropertyGroup foundPropertyGroup = null;
            foreach (BuildPropertyGroup propertyGroup in project.PropertyGroups)
            {
                foreach (BuildProperty item in propertyGroup)
                {
                    if (item.Name == propertyName)
                    {
                        foundPropertyGroup = propertyGroup;
                        break;
                    }
                }
                if (foundPropertyGroup != null)
                {
                    break;
                }
            }
            return foundPropertyGroup;
        }

        private static BuildProperty SetOrCreateProperty(BuildPropertyGroup group, string propertyName, string propertyValue)
        {
            if (propertyValue == null) throw new ArgumentNullException("propertyValue");
            BuildProperty foundBuildProperty = GetBuildProperty(group, propertyName);
            if (foundBuildProperty != null)
            {
                foundBuildProperty.Value = propertyValue;
                return foundBuildProperty;
            }
            return group.AddNewProperty(propertyName, propertyValue);
        }

        private static BuildProperty GetBuildProperty(BuildPropertyGroup group, string PropertyName)
        {
            BuildProperty foundBuildProperty = null;
            foreach (BuildProperty buildProperty in group)
            {
                if (buildProperty.Name == PropertyName)
                {
                    foundBuildProperty = buildProperty;
                    break;
                }
            }
            return foundBuildProperty;
        }

        #endregion

        #region Item Utilities

        private static BuildItemGroup GetBuildItemGroup(Project project, string itemName)
        {
            BuildItemGroup foundItemGroup = null;
            foreach (BuildItemGroup itemGroup in project.ItemGroups)
            {
                foreach (BuildItem item in itemGroup)
                {
                    if (item.Name == itemName)
                    {
                        foundItemGroup = itemGroup;
                        break;
                    }
                }
                if (foundItemGroup != null)
                {
                    break;
                }
            }
            if (foundItemGroup == null)
            {
                foundItemGroup = project.AddNewItemGroup();
            }
            return foundItemGroup;
        }

        private BuildItem GetBuildItem(string itemName, string includeValue, out BuildItemGroup foundItemGroup)
        {
            foreach (BuildItemGroup itemGroup in _project.ItemGroups)
            {
                BuildItem foundBuildItem = FindBuildItemInGroup(itemGroup, itemName, includeValue);
                if (foundBuildItem != null)
                {
                    foundItemGroup = itemGroup;
                    return foundBuildItem;
                }
            }
            foundItemGroup = null;
            return null;
        }

        private BuildItem FindOrCreateItem(BuildItemGroup group, string itemName, string itemInclude)
        {
            BuildItem foundBuildItem = FindBuildItemInGroup(group, itemName, itemInclude);
            if (foundBuildItem == null)
            {
                BuildItemGroup foundItemGroup;
                foundBuildItem = GetBuildItem(itemName, itemInclude, out foundItemGroup);
            }
            if (foundBuildItem != null)
            {
                return foundBuildItem;
            }
            else
            {
                return group.AddNewItem(itemName, itemInclude);
            }
        }

	    private static BuildItem FindBuildItemInGroup(BuildItemGroup group, string itemName, string itemInclude)
	    {
	        foreach (BuildItem buildItem in group)
	        {
                //Console.WriteLine(item.Name + " : " + item.Include);
	            if (buildItem.Name == itemName && buildItem.Include == itemInclude)
	            {
	                return buildItem;
	            }
	        }
	        return null;
	    }

	    #endregion

        #endregion

	}
}
